package com.khstudio.videocapture.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.khstudio.api.util.KhLog;

public class VideoFadeLayout_Kh extends ViewGroup implements View.OnClickListener {

    private static final int AUTO_HIDE              = 0x0001;
    private static final int FADE_IN                = 0x0002;
    private static final int FADE_OUT               = 0x0003;

    private static final int FADE_DURATION = 1000;
    private static final int FADE_DELAY = 10;

    private Context mContext;

    private View mLeftView;
    private int  mLeftPos;
    private int  mLeftHide;

    private View mRightView;
    private int  mRightPos;
    private int  mRightHide;

    private View mTopView;
    private int  mTopPos;
    private int  mTopHide;

    private View mBottomView;
    private int  mBottomPos;
    private int  mBottomHide;

    private View mCenterView;
    private int  mCenterTransparent;

    private long mFadeLoopTimeMs;

    private boolean isEnabled;
    private boolean isShown;

    private final Handler mFadeHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case AUTO_HIDE: {
                    if(isShown) {
                        _fadeOut(true);
                    }
                } break;
                case FADE_IN: {
                    _fadeIn(false);
                    requestLayout();
                } break;
                case FADE_OUT: {
                    _fadeOut(false);
                    requestLayout();
                } break;
            }
        }
    };

    public VideoFadeLayout_Kh(Context context) {
        this(context, null);
    }

    public VideoFadeLayout_Kh(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VideoFadeLayout_Kh(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mContext = context;

        mLeftView = null;
        mLeftPos = 0;
        mLeftHide = 0;

        mRightView = null;
        mRightPos = 0;
        mRightHide = 0;

        mTopView = null;
        mTopPos = 0;
        mTopHide = 0;

        mBottomView = null;
        mBottomPos = 0;
        mBottomHide = 0;

        mCenterView = null;
        mCenterTransparent = 100;

        mFadeLoopTimeMs = 0;

        isEnabled = true;
        isShown = true;

        _initAttribute(attrs, defStyle);

        this.setOnClickListener(this);

//        mFadeHandler.sendEmptyMessageDelayed(AUTO_HIDE, 5000);
    }

    public void setGroupEnabled(boolean enabled) {
        if(isEnabled != enabled) {
            isEnabled = enabled;

            if(mLeftView != null && mLeftView.getVisibility() == View.VISIBLE) {
                _groupEnabled(mLeftView, isEnabled);
            }

            if(mRightView != null && mRightView.getVisibility() == View.VISIBLE) {
                _groupEnabled(mRightView, isEnabled);
            }

            if(mTopView != null && mTopView.getVisibility() == View.VISIBLE) {
                _groupEnabled(mTopView, isEnabled);
            }

            if(mBottomView != null && mBottomView.getVisibility() == View.VISIBLE) {
                _groupEnabled(mBottomView, isEnabled);
            }

            if(mCenterView != null && mCenterView.getVisibility() == View.VISIBLE) {
                _groupEnabled(mCenterView, isEnabled);
            }
        }
    }

    public boolean getGroupEnabled() {
        return isEnabled;
    }

    public void setLeftView(View v) {
        mLeftView = v;
        addView(mLeftView);

        requestLayout();
    }

    public void setRightView(View v) {
        mRightView = v;
        addView(mRightView);

        requestLayout();
    }

    public void setTopView(View v) {
        mTopView = v;
        addView(mTopView);

        requestLayout();
    }

    public void setBottomView(View v) {
        mBottomView = v;
        addView(mBottomView);

        requestLayout();
    }

    public void setCenterView(View v) {
        mCenterView = v;
        addView(mCenterView);

        requestLayout();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(changed)
            KhLog.v("KhVideoFadeLayout : onLayout l = %d t = %d r = %d b = %d", l, t, r, b);
        int width = r - l;
        int height = b - t;

        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;

        int padding_l = getPaddingLeft();
        int padding_t = getPaddingTop();
        int padding_r = getPaddingRight();
        int padding_b = getPaddingBottom();

        if(mLeftView != null && mLeftView.getVisibility() == View.VISIBLE) {
            mLeftHide = mLeftView.getMeasuredWidth();
            left = padding_l - mLeftPos;
            top = padding_t;
            right = left + mLeftHide;
            bottom = top + mLeftView.getMeasuredHeight();
            mLeftView.layout(left, top, right, bottom);
        }

        if(mRightView != null && mRightView.getVisibility() == View.VISIBLE) {
            mRightHide = mRightView.getMeasuredWidth();
            left = width - padding_r - mRightHide + mRightPos;
            top = padding_t;
            right = left + mRightHide;
            bottom = top + mRightView.getMeasuredHeight();
            mRightView.layout(left, top, right, bottom);
        }

        if(mTopView != null && mTopView.getVisibility() == View.VISIBLE) {
            mTopHide = mTopView.getMeasuredHeight();
            left = padding_l + (width - padding_l - padding_r - mTopView.getMeasuredWidth()) / 2;
            top = padding_t - mTopPos;
            right = left + mTopView.getMeasuredWidth();
            bottom = top + mTopHide;
            mTopView.layout(left, top, right, bottom);
        }

        if(mBottomView != null && mBottomView.getVisibility() == View.VISIBLE) {
            mBottomHide = mBottomView.getMeasuredHeight();
            left = padding_l + (width - padding_l - padding_r - mBottomView.getMeasuredWidth()) / 2;
            top = height - padding_b - mBottomHide + mBottomPos;
            right = left + mBottomView.getMeasuredWidth();
            bottom = top + mBottomHide;
            mBottomView.layout(left, top, right, bottom);
        }

        if(mCenterView != null && mCenterView.getVisibility() == View.VISIBLE) {
            left = padding_l + (width - padding_l - padding_r - mCenterView.getMeasuredWidth()) / 2;
            top = padding_t + (height - padding_t - padding_b - mCenterView.getMeasuredHeight()) / 2;
            right = left + mCenterView.getMeasuredWidth();
            bottom = top + mCenterView.getMeasuredHeight();
            mCenterView.layout(left, top, right, bottom);
        }
    }

    @Override
    public void onClick(View v) {
        // if(isEnabled == false) return;

        if (v == this) {
            KhLog.i("KhVideoCaptureShowHideGroup : onClick");
            if (isShown) {
                _fadeOut(true);
            } else {
                _fadeIn(true);
            }
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                KhLog.i("KhVideoCaptureShowHideGroup : dispatchTouchEvent ACTION_UP");
//                mFadeHandler.removeMessages(AUTO_HIDE);
//                mFadeHandler.sendEmptyMessageDelayed(AUTO_HIDE, 5000);
            break;
        }
        return super.dispatchTouchEvent(ev);
    }

    private void _initAttribute(AttributeSet attrs, int defStyle) {
        if (attrs == null) {
            return;
        }

        int[] ids = new int[attrs.getAttributeCount()];
        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            ids[i] = attrs.getAttributeNameResource(i);
        }

        TypedArray a = mContext.obtainStyledAttributes(attrs, ids, defStyle, 0);

        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            String attrName = attrs.getAttributeName(i);
            if (attrName == null)
                continue;

        }

        a.recycle();
    }

    private void _groupEnabled(View view, boolean enabled) {
        view.setEnabled(enabled);

        if (view instanceof ViewGroup) {
            ViewGroup group = (ViewGroup) view;

            for (int idx = 0; idx < group.getChildCount(); idx++) {
                _groupEnabled(group.getChildAt(idx), enabled);
            }
        }
    }

    private void _fadeIn(boolean start) {
        if (start) {
            isShown = true;

            if(mLeftView != null) {
                mLeftView.setVisibility(View.VISIBLE);
            }
            if(mRightView != null) {
                mRightView.setVisibility(View.VISIBLE);
            }
            if(mTopView != null) {
                mTopView.setVisibility(View.VISIBLE);
            }
            if(mBottomView != null) {
                mBottomView.setVisibility(View.VISIBLE);
            }
            if(mCenterView != null) {
                mCenterView.setVisibility(View.VISIBLE);
            }

            mFadeHandler.removeMessages(FADE_IN);
            if(mFadeHandler.hasMessages(FADE_OUT)) {
                mFadeHandler.removeMessages(FADE_OUT);
                long remainTime = FADE_DURATION - (System.currentTimeMillis() - mFadeLoopTimeMs);
                mFadeLoopTimeMs = System.currentTimeMillis() - remainTime;
            } else {
                mFadeLoopTimeMs = System.currentTimeMillis();
            }
            mFadeHandler.sendEmptyMessage(FADE_IN);
        } else {
            boolean isNext = false;
            long loopTapTime = System.currentTimeMillis() - mFadeLoopTimeMs;
            float loopAlpha = (float)loopTapTime / FADE_DURATION;
            if (loopAlpha >= 1) {
                loopAlpha = 1;
            } else {
                isNext = true;
            }

            if (mLeftView != null && mLeftView.getVisibility() == View.VISIBLE) {
                mLeftView.setAlpha(loopAlpha);
                mLeftPos = (int) (mLeftHide * (FADE_DURATION - loopTapTime) / FADE_DURATION);
                if (mLeftPos <= 0) {
                    mLeftPos = 0;
                } else {
                    isNext = true;
                }
            }

            if (mRightView != null && mRightView.getVisibility() == View.VISIBLE) {
                mRightView.setAlpha(loopAlpha);
                mRightPos = (int) (mRightHide * (FADE_DURATION - loopTapTime) / FADE_DURATION);
                if (mRightPos <= 0) {
                    mRightPos = 0;
                } else {
                    isNext = true;
                }
            }

            if (mTopView != null && mTopView.getVisibility() == View.VISIBLE) {
                mTopView.setAlpha(loopAlpha);
                mTopPos = (int) (mTopHide * (FADE_DURATION - loopTapTime) / FADE_DURATION);
                if (mTopPos <= 0) {
                    mTopPos = 0;
                } else {
                    isNext = true;
                }
            }

            if (mBottomView != null && mBottomView.getVisibility() == View.VISIBLE) {
                mBottomView.setAlpha(loopAlpha);
                mBottomPos = (int) (mBottomHide * (FADE_DURATION - loopTapTime) / FADE_DURATION);
                if (mBottomPos <= 0) {
                    mBottomPos = 0;
                } else {
                    isNext = true;
                }
            }

            if (mCenterView != null && mCenterView.getVisibility() == View.VISIBLE) {
                mCenterView.setAlpha(loopAlpha);
            }

            if (isNext) {
                mFadeHandler.sendEmptyMessageDelayed(FADE_IN, FADE_DELAY);
            }
        }
    }

    private void _fadeOut(boolean start) {
        if (start) {
            isShown = false;

            if(mFadeHandler.hasMessages(FADE_IN)) {
                mFadeHandler.removeMessages(FADE_IN);
                long remainTime = FADE_DURATION - (System.currentTimeMillis() - mFadeLoopTimeMs);
                mFadeLoopTimeMs = System.currentTimeMillis() - remainTime;
            } else {
                mFadeLoopTimeMs = System.currentTimeMillis();
            }
            mFadeHandler.removeMessages(FADE_OUT);
            mFadeHandler.sendEmptyMessage(FADE_OUT);
        } else {
            boolean isNext = false;
            long loopTapTime = System.currentTimeMillis() - mFadeLoopTimeMs;
            float loopAlpha = (float)(FADE_DURATION - loopTapTime) / FADE_DURATION;
            if (loopAlpha <= 0) {
                loopAlpha = 0;
            } else {
                isNext = true;
            }

            if (mLeftView != null && mLeftView.getVisibility() == View.VISIBLE) {
                mLeftView.setAlpha(loopAlpha);
                mLeftPos = (int) (mLeftHide * loopTapTime / FADE_DURATION);
                if (mLeftPos >= mLeftHide) {
                    mLeftPos = mLeftHide;
                    mLeftView.setVisibility(View.GONE);
                } else {
                    isNext = true;
                }
            }

            if (mRightView != null && mRightView.getVisibility() == View.VISIBLE) {
                mRightView.setAlpha(loopAlpha);
                mRightPos = (int) (mRightHide * loopTapTime / FADE_DURATION);
                if (mRightPos >= mRightHide) {
                    mRightPos = mRightHide;
                    mRightView.setVisibility(View.GONE);
                } else {
                    isNext = true;
                }
            }

            if (mTopView != null && mTopView.getVisibility() == View.VISIBLE) {
                mTopView.setAlpha(loopAlpha);
                mTopPos = (int) (mTopHide * loopTapTime / FADE_DURATION);
                if (mTopPos >= mTopHide) {
                    mTopPos = mTopHide;
                    mTopView.setVisibility(View.GONE);
                } else {
                    isNext = true;
                }
            }

            if (mBottomView != null && mBottomView.getVisibility() == View.VISIBLE) {
                mBottomView.setAlpha(loopAlpha);
                mBottomPos = (int) (mBottomHide * loopTapTime / FADE_DURATION);
                if (mBottomPos >= mBottomHide) {
                    mBottomPos = mBottomHide;
                    mBottomView.setVisibility(View.GONE);
                } else {
                    isNext = true;
                }
            }

            if (mCenterView != null && mCenterView.getVisibility() == View.VISIBLE) {
                mCenterView.setAlpha(loopAlpha);
                if(loopAlpha <= 0) {
                    mCenterView.setVisibility(View.GONE);
                }
            }

            if (isNext) {
                mFadeHandler.sendEmptyMessageDelayed(FADE_OUT, FADE_DELAY);
            }
        }
    }
}
